﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

namespace YJKTools.ExportNavisworks
{
	public partial class ExportSettingForm : System.Windows.Forms.Form
	{
		public ExportSettingForm(ExternalCommandData cmdData)
		{
			this.m_doc = cmdData.Application.ActiveUIDocument.Document;
			this.m_selection = cmdData.Application.ActiveUIDocument.Selection;
			this.InitializeComponent();
			this.m_levels = this.GetAllLevels(this.m_doc);
			this.m_categories = this.GetAllCategories(this.m_doc);
			this.m_mepSystems = this.GetAllMepSystems(this.m_doc);
			this.InitLevelState(this.m_levels);
			this.InitCategoryState(this.m_categories);
			this.InitMEPSystemState(this.m_mepSystems);
			if (!this.ReadData())
			{
				this.m_mode = 0;
				this.tbBottomOffset.Text = "0";
				this.m_bottomOffset = this.tbBottomOffset.Text;
				this.tbTopOffset.Text = "0";
				this.m_topOffset = this.tbTopOffset.Text;
			}
			this.InitLevelInfo(this.m_levels);
			if (this.m_mode == 0)
			{
				this.rbCategory.Checked = true;
				this.rbSystem.Checked = false;
				this.InitCategoryInfo(this.m_categories);
				this.btnPickSystem.Hide();
				return;
			}
			if (1 == this.m_mode)
			{
				this.rbSystem.Checked = true;
				this.rbCategory.Checked = false;
				this.InitMEPSystemInfo(this.m_mepSystems);
				this.btnPickSystem.Show();
			}
		}

		private List<Level> GetAllLevels(Document doc)
		{
			return this.GetSortLevels(doc, double.MinValue, double.MaxValue);
		}

		private List<Category> GetAllCategories(Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc, doc.ActiveView.Id);
			ICollection<Element> collection = filteredElementCollector.OfClass(typeof(HostObject)).ToElements();
			FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(doc);
			ICollection<Element> collection2 = filteredElementCollector2.OfClass(typeof(FamilyInstance)).ToElements();
			List<Category> list = new List<Category>();
			foreach (Element element in collection)
			{
				if (element.IsPhaseCreatedValid(element.CreatedPhaseId) && !this.IsExistCategory(list, element.Category))
				{
					list.Add(element.Category);
				}
			}
			foreach (Element element2 in collection2)
			{
				if (element2.IsPhaseCreatedValid(element2.CreatedPhaseId) && !this.IsExistCategory(list, element2.Category))
				{
					list.Add(element2.Category);
				}
			}
			list.Sort(new CategoryComparer());
			return list;
		}

		private bool IsExistCategory(List<Category> categories, Category category)
		{
			foreach (Category category2 in categories)
			{
				if (category2.Id == category.Id)
				{
					return true;
				}
			}
			return false;
		}

		private List<MEPSystem> GetAllMepSystems(Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			ICollection<Element> collection = filteredElementCollector.OfClass(typeof(MechanicalSystem)).ToElements();
			FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(doc);
			ICollection<Element> collection2 = filteredElementCollector2.OfClass(typeof(PipingSystem)).ToElements();
			List<MEPSystem> list = new List<MEPSystem>();
			foreach (Element element in collection)
			{
				list.Add(element as MEPSystem);
			}
			foreach (Element element2 in collection2)
			{
				list.Add(element2 as MEPSystem);
			}
			return list;
		}

		private void InitLevelState(List<Level> levels)
		{
			this.m_levelState = new List<bool>();
			for (int i = 0; i < levels.Count; i++)
			{
				this.m_levelState.Add(true);
			}
		}

		private void InitCategoryState(List<Category> categories)
		{
			this.m_categoryState = new List<bool>();
			for (int i = 0; i < categories.Count; i++)
			{
				this.m_categoryState.Add(true);
			}
		}

		private void InitMEPSystemState(List<MEPSystem> mepSystems)
		{
			this.m_systemState = new List<bool>();
			for (int i = 0; i < mepSystems.Count; i++)
			{
				this.m_systemState.Add(true);
			}
		}

		private void InitLevelInfo(List<Level> levels)
		{
			this.DGVTable.Rows.Clear();
			for (int i = 0; i < levels.Count; i++)
			{
				bool sel = this.m_levelState[i];
				string name = levels[i].Name;
				double elevation = levels[i].Elevation;
				double bottomOffset = 0.0;
				double topElevation;
				if (levels.Count - 1 == i)
				{
					topElevation = elevation + AssistFunc.mmToFeet(4000.0);
				}
				else
				{
					topElevation = levels[i + 1].Elevation;
				}
				double topOffset = 0.0;
				LevelInfo levelInfo = new LevelInfo(sel, name, elevation, bottomOffset, topElevation, topOffset);
				this.AddfloorRow(levelInfo);
			}
		}

		private void InitCategoryInfo(List<Category> categories)
		{
			this.clbItems.Items.Clear();
			foreach (Category category in categories)
			{
				this.clbItems.Items.Add(category.Name);
			}
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				this.clbItems.SetItemChecked(i, this.m_categoryState[i]);
			}
		}

		private void InitMEPSystemInfo(List<MEPSystem> mepSystems)
		{
			this.clbItems.Items.Clear();
			foreach (MEPSystem mepsystem in mepSystems)
			{
				this.clbItems.Items.Add(mepsystem.Name);
			}
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				this.clbItems.SetItemChecked(i, this.m_systemState[i]);
			}
		}

		private void AddfloorRow(LevelInfo levelInfo)
		{
			DataGridViewRow dataGridViewRow = new DataGridViewRow();
			dataGridViewRow.DefaultCellStyle.BackColor = this.DGVTable.BackgroundColor;
			DataGridViewCheckBoxCell dataGridViewCheckBoxCell = new DataGridViewCheckBoxCell();
			dataGridViewCheckBoxCell.Value = levelInfo.m_Sel;
            dataGridViewCheckBoxCell.Style.BackColor = System.Drawing.Color.White;
			dataGridViewRow.Cells.Add(dataGridViewCheckBoxCell);
			DataGridViewTextBoxCell dataGridViewTextBoxCell = new DataGridViewTextBoxCell();
			dataGridViewTextBoxCell.Value = levelInfo.m_FloorName;
            dataGridViewTextBoxCell.Style.BackColor = System.Drawing.Color.Gainsboro;
			dataGridViewRow.Cells.Add(dataGridViewTextBoxCell);
			DataGridViewTextBoxCell dataGridViewTextBoxCell2 = new DataGridViewTextBoxCell();
			dataGridViewTextBoxCell2.Value = AssistFunc.feetToMM(levelInfo.m_BottomElevation).ToString("f0");
            dataGridViewTextBoxCell2.Style.BackColor = System.Drawing.Color.Gainsboro;
			dataGridViewRow.Cells.Add(dataGridViewTextBoxCell2);
			DataGridViewTextBoxCell dataGridViewTextBoxCell3 = new DataGridViewTextBoxCell();
			dataGridViewTextBoxCell3.Value = AssistFunc.feetToMM(levelInfo.m_BottomOffset).ToString("f0");
            dataGridViewTextBoxCell3.Style.BackColor = System.Drawing.Color.White;
			dataGridViewRow.Cells.Add(dataGridViewTextBoxCell3);
			DataGridViewTextBoxCell dataGridViewTextBoxCell4 = new DataGridViewTextBoxCell();
			dataGridViewTextBoxCell4.Value = AssistFunc.feetToMM(levelInfo.m_TopElevation).ToString("f0");
            dataGridViewTextBoxCell4.Style.BackColor = System.Drawing.Color.Gainsboro;
			dataGridViewRow.Cells.Add(dataGridViewTextBoxCell4);
			DataGridViewTextBoxCell dataGridViewTextBoxCell5 = new DataGridViewTextBoxCell();
			dataGridViewTextBoxCell5.Value = AssistFunc.feetToMM(levelInfo.m_TopOffset).ToString("f0");
            dataGridViewTextBoxCell5.Style.BackColor = System.Drawing.Color.White;
			dataGridViewRow.Cells.Add(dataGridViewTextBoxCell5);
			this.DGVTable.Rows.Add(dataGridViewRow);
		}

		public List<LevelInfo> GetSelectedLevelInfo()
		{
			List<LevelInfo> list = new List<LevelInfo>();
			for (int i = 0; i < this.DGVTable.Rows.Count; i++)
			{
				DataGridViewRow dataGridViewRow = this.DGVTable.Rows[i];
				bool flag = Convert.ToBoolean(dataGridViewRow.Cells[0].Value.ToString());
				if (flag)
				{
					string floorName = dataGridViewRow.Cells[1].Value.ToString();
					double bottomElevation = AssistFunc.mmToFeet(Convert.ToDouble(dataGridViewRow.Cells[2].Value.ToString()));
					double bottomOffset = AssistFunc.mmToFeet(Convert.ToDouble(dataGridViewRow.Cells[3].Value.ToString()));
					double topElevation = AssistFunc.mmToFeet(Convert.ToDouble(dataGridViewRow.Cells[4].Value.ToString()));
					double topOffset = AssistFunc.mmToFeet(Convert.ToDouble(dataGridViewRow.Cells[5].Value.ToString()));
					LevelInfo item = new LevelInfo(flag, floorName, bottomElevation, bottomOffset, topElevation, topOffset);
					list.Add(item);
				}
			}
			return list;
		}

		public IList<ElementId> GetNoSelectedCategories()
		{
			IList<ElementId> list = new List<ElementId>();
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				if (!this.clbItems.GetItemChecked(i))
				{
					list.Add(this.m_categories[i].Id);
				}
			}
			return list;
		}

		public List<MEPSystem> GetSelectedMEPSystems()
		{
			List<MEPSystem> list = new List<MEPSystem>();
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				if (this.clbItems.GetItemChecked(i))
				{
					list.Add(this.m_mepSystems[i]);
				}
			}
			return list;
		}

		private List<Level> GetSortLevels(Document doc, double bottom, double top)
		{
			List<Level> list = new List<Level>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			ICollection<Element> collection = filteredElementCollector.OfClass(typeof(Level)).ToElements();
			foreach (Element element in collection)
			{
				Level level = element as Level;
				double elevation = level.Elevation;
				if (elevation >= bottom && elevation <= top)
				{
					list.Add(level);
				}
			}
			list.Sort(new LevelComparer());
			return list;
		}

		private void tbBottomOffset_TextChanged(object sender, EventArgs e)
		{
			if (1 == this.tbBottomOffset.Text.Length && this.tbBottomOffset.Text.CompareTo("-") == 0)
			{
				return;
			}
			if (!this.IsValidating(this.tbBottomOffset.Text, -4000.0, 4000.0))
			{
				TaskDialog.Show("盈建科", "偏移值的合法范围在-4000mm～4000mm之间。");
				this.tbBottomOffset.Text = this.m_bottomOffset;
				return;
			}
			this.m_bottomOffset = this.tbBottomOffset.Text;
		}

		private void tbTopOffset_TextChanged(object sender, EventArgs e)
		{
			if (1 == this.tbTopOffset.Text.Length && this.tbTopOffset.Text.CompareTo("-") == 0)
			{
				return;
			}
			if (!this.IsValidating(this.tbTopOffset.Text, -4000.0, 4000.0))
			{
				TaskDialog.Show("盈建科", "偏移值的合法范围在-4000mm～4000mm之间。");
				this.tbTopOffset.Text = this.m_topOffset;
				return;
			}
			this.m_topOffset = this.tbTopOffset.Text;
		}

		private bool IsValidating(string numStr, double minRange, double maxRange)
		{
			try
			{
				double val = Convert.ToDouble(numStr);
				if (this.LessThan(val, minRange))
				{
					return false;
				}
				if (this.GreaterThan(val, maxRange))
				{
					return false;
				}
			}
			catch (Exception ex)
			{
				ex.ToString();
				return false;
			}
			return true;
		}

		private bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		private bool GreaterThan(double val1, double val2)
		{
			return val1 - val2 > 1E-09;
		}

		private void ExportSettingForm_FormClosing(object sender, FormClosingEventArgs e)
		{
			this.SaveData();
		}

		private bool ReadData()
		{
			string tempPath = Path.GetTempPath();
			string path = tempPath + "ExportSettingForm.dat";
			if (!File.Exists(path))
			{
				return false;
			}
			FileStream fileStream = new FileStream(path, FileMode.Open);
			StreamReader streamReader = new StreamReader(fileStream);
			streamReader.BaseStream.Seek(0L, SeekOrigin.Begin);
			try
			{
				string s = streamReader.ReadLine();
				this.m_mode = int.Parse(s);
				this.m_bottomOffset = streamReader.ReadLine();
				double.Parse(this.m_bottomOffset);
				this.tbBottomOffset.Text = this.m_bottomOffset;
				this.m_topOffset = streamReader.ReadLine();
				double.Parse(this.m_topOffset);
				this.tbTopOffset.Text = this.m_topOffset;
			}
			catch
			{
				return false;
			}
			finally
			{
				streamReader.Close();
				fileStream.Close();
			}
			return true;
		}

		private void SaveData()
		{
			string tempPath = Path.GetTempPath();
			string path = tempPath + "ExportSettingForm.dat";
			FileStream fileStream = new FileStream(path, FileMode.Create);
			StreamWriter streamWriter = new StreamWriter(fileStream);
			streamWriter.WriteLine(this.m_mode);
			streamWriter.WriteLine(this.m_bottomOffset);
			streamWriter.WriteLine(this.m_topOffset);
			streamWriter.Flush();
			streamWriter.Close();
			fileStream.Close();
		}

		private void rbCategory_Click(object sender, EventArgs e)
		{
			if (1 == this.m_mode)
			{
				this.m_mode = 0;
				this.SaveMEPSystemState();
				this.InitCategoryInfo(this.m_categories);
				this.btnPickSystem.Hide();
			}
		}

		private void rbSystem_Click(object sender, EventArgs e)
		{
			if (this.m_mode == 0)
			{
				this.m_mode = 1;
				this.SaveCategoryState();
				this.InitMEPSystemInfo(this.m_mepSystems);
				this.btnPickSystem.Show();
			}
		}

		private void btnSelAll_Click(object sender, EventArgs e)
		{
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				this.clbItems.SetItemChecked(i, true);
			}
		}

		private void btnSelReverse_Click(object sender, EventArgs e)
		{
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				this.clbItems.SetItemChecked(i, !this.clbItems.GetItemChecked(i));
			}
		}

		public List<ElementId> GetElementsBySystem(MEPSystem mepSys)
		{
			List<ElementId> list = new List<ElementId>();
			MechanicalSystem mechanicalSystem = mepSys as MechanicalSystem;
			if (mechanicalSystem != null)
			{
				ElementSet ductNetwork = mechanicalSystem.DuctNetwork;
				ElementSet elements = mechanicalSystem.Elements;
				foreach (object obj in ductNetwork)
				{
					Element element = (Element)obj;
					list.Add(element.Id);
				}
				foreach (object obj2 in elements)
				{
					Element element2 = (Element)obj2;
					list.Add(element2.Id);
				}
			}
			PipingSystem pipingSystem = mepSys as PipingSystem;
			if (pipingSystem != null)
			{
				ElementSet pipingNetwork = pipingSystem.PipingNetwork;
				ElementSet elements2 = pipingSystem.Elements;
				foreach (object obj3 in pipingNetwork)
				{
					Element element3 = (Element)obj3;
					list.Add(element3.Id);
				}
				foreach (object obj4 in elements2)
				{
					Element element4 = (Element)obj4;
					list.Add(element4.Id);
				}
			}
			return list;
		}

		private void SaveLevelState()
		{
			this.m_levelState.Clear();
			this.m_levelState = new List<bool>();
			for (int i = 0; i < this.DGVTable.Rows.Count; i++)
			{
				DataGridViewRow dataGridViewRow = this.DGVTable.Rows[i];
				bool item = Convert.ToBoolean(dataGridViewRow.Cells[0].Value.ToString());
				this.m_levelState.Add(item);
			}
		}

		private void SaveCategoryState()
		{
			this.m_categoryState.Clear();
			this.m_categoryState = new List<bool>();
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				bool itemChecked = this.clbItems.GetItemChecked(i);
				this.m_categoryState.Add(itemChecked);
			}
		}

		private void SaveMEPSystemState()
		{
			this.m_systemState.Clear();
			this.m_systemState = new List<bool>();
			for (int i = 0; i < this.clbItems.Items.Count; i++)
			{
				bool itemChecked = this.clbItems.GetItemChecked(i);
				this.m_systemState.Add(itemChecked);
			}
		}

		public void SetSystemStateByElement(Element element)
		{
			foreach (MEPSystem mepsystem in this.m_mepSystems)
			{
				List<ElementId> elementsBySystem = this.GetElementsBySystem(mepsystem);
				if (elementsBySystem.Contains(element.Id))
				{
					int index = this.m_mepSystems.IndexOf(mepsystem);
					this.clbItems.SetItemChecked(index, true);
				}
			}
		}

		private void ExportSettingForm_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Escape)
			{
				base.Close();
			}
		}

		private void btnOK_Click(object sender, EventArgs e)
		{
			bool flag = false;
			for (int i = 0; i < this.DGVTable.Rows.Count; i++)
			{
				DataGridViewRow dataGridViewRow = this.DGVTable.Rows[i];
				bool flag2 = Convert.ToBoolean(dataGridViewRow.Cells[0].Value.ToString());
				if (flag2)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				base.DialogResult = DialogResult.None;
				TaskDialog.Show("盈建科", "楼层列表不能空选。");
				return;
			}
			flag = false;
			for (int j = 0; j < this.clbItems.Items.Count; j++)
			{
				bool itemChecked = this.clbItems.GetItemChecked(j);
				if (itemChecked)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				base.DialogResult = DialogResult.None;
				if (this.m_mode == 0)
				{
					TaskDialog.Show("盈建科", "类型列表不能空选。");
					return;
				}
				if (1 == this.m_mode)
				{
					TaskDialog.Show("盈建科", "系统列表不能空选。");
				}
			}
		}

		private void DGVTable_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
		{
			this.m_editOffset = this.DGVTable.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
		}

		private void DGVTable_CellValueChanged(object sender, DataGridViewCellEventArgs e)
		{
			int rowIndex = e.RowIndex;
			int columnIndex = e.ColumnIndex;
			if (rowIndex < 0 || columnIndex < 0)
			{
				return;
			}
			if (3 == columnIndex || 5 == columnIndex)
			{
				if (this.DGVTable.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == null)
				{
					TaskDialog.Show("盈建科", "偏移值不能为空。");
					this.DGVTable.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = this.m_editOffset;
					return;
				}
				string numStr = this.DGVTable.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
				if (!this.IsValidating(numStr, -4000.0, 4000.0))
				{
					TaskDialog.Show("盈建科", "偏移值的合法范围在-4000mm～4000mm之间。");
					this.DGVTable.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = this.m_editOffset;
				}
			}
		}

		private void btnApply_Click(object sender, EventArgs e)
		{
			double num = 0.0;
			try
			{
				num = Convert.ToDouble(this.tbBottomOffset.Text);
			}
			catch
			{
				TaskDialog.Show("盈建科", "底偏移不合法。");
				return;
			}
			double num2 = 0.0;
			try
			{
				num2 = Convert.ToDouble(this.tbTopOffset.Text);
			}
			catch
			{
				TaskDialog.Show("盈建科", "顶偏移不合法。");
				return;
			}
			foreach (object obj in ((IEnumerable)this.DGVTable.Rows))
			{
				DataGridViewRow dataGridViewRow = (DataGridViewRow)obj;
				dataGridViewRow.Cells[3].Value = num;
			}
			foreach (object obj2 in ((IEnumerable)this.DGVTable.Rows))
			{
				DataGridViewRow dataGridViewRow2 = (DataGridViewRow)obj2;
				dataGridViewRow2.Cells[5].Value = num2;
			}
		}

		public const double _epsDouble = 1E-09;

		private Document m_doc;

		private Selection m_selection;

		public int m_mode;

		private string m_bottomOffset = "0";

		private string m_topOffset = "0";

		private string m_editOffset = "0";

		private List<Level> m_levels;

		private List<Category> m_categories;

		private List<MEPSystem> m_mepSystems;

		public List<bool> m_levelState;

		public List<bool> m_categoryState;

		public List<bool> m_systemState;
	}
}
